using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

using TFlex.Model;
using TFlex.QualityManagement;

namespace QualityManagementSample
{
    public class SampleLayerNamesLogic : LogicBase
    {
        public override Guid Uid => new System.Guid("07bc3705-0bc8-4833-b515-2cc8fb1eaa06");

        public override ActionInfo GetActionInfo(GetActionInfoContext context)
        {
            var res = new ActionInfo()
            {
                LogicUid = Uid,
                Group = "Примеры",
                Name = "Пользовательская проверка имен слоев",
                Description = "Пример пользовательской проверки, реализованной в отдельной сборке (dll)",
            };
            res.AddTag("2D/3D");
            return res;
        }

        private string GetNameError(String name)
        {
            if(name.Length > 30)
                return "Слишком длинное имя слоя: " + name;

            string pattern = @"\p{IsCyrillic}|\d|_| ";
            if (Regex.Matches(name, pattern).Count < name.Length)
                return "Имя слоя содержит запрещённые символы: " + name;

            return null;
        }

        public override RunResult Run(RunContext context)
        {
            RunResult result = new RunResult() { IsFixable = true };
            var doc = context.Document;
            foreach (var layer in doc.GetLayers())
            {
                if (GetNameError(layer.Name) is string error)
                {
                    result.State = RunResultState.Error;
                    result.ShortMessage = "Ошибка в именах слоев";
                    result.Entries.Add(new RunResultEntry(layer)
                    {
                         IsFixable = true,
                         Cause = RunResultEntryCause.Error,
                         ShortMessage = error
                    });
                }
            }
            return result;
        }

        public override FixResult Fix(FixContext context, FixTask task)
        {
            var doc = context.Document;
            var usedNames = new HashSet<String>(doc.GetLayers().Select(l => l.Name));

            int index = 1;
            foreach (var entry in task.Entries)
            {
                foreach (var layer in entry.ObjectIds.GetModelObjects<Layer>(doc))
                {
                    string name;
                    do
                        name = $"Слой_{index++}";
                    while (usedNames.Contains(name));
                    usedNames.Add(name);
                    layer.Name = name;
                }
            }
            return new FixResult() { State = FixResultState.Fixed };
        }
    }
}
